package com.pochogastos.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.naming.NamingException;

import com.pochogastos.db.DBManager;
import com.pochogastos.model.Categoria;
import com.pochogastos.model.Gasto;
import com.pochogastos.model.GastoVO;

public class GastoDAO {
	
private static GastoDAO instancia;
	
	public static GastoDAO getInstance(){
		if(instancia == null)
			instancia = new GastoDAO();
		return instancia;
	}
	
	public int insertGasto(String descripcion, String fecha, String monto, String categoria,String idUsuario) throws SQLException, ClassNotFoundException, NamingException{
			Connection conn = DBManager.getInstance().getConnection();
			PreparedStatement pstmt = conn.prepareStatement("INSERT INTO gastos.gastos (descripcion,fecha,id_categoria,monto,id_usuario) VALUES (?,DATE(?),?,?,?)", Statement.RETURN_GENERATED_KEYS);
			pstmt.setString(1, descripcion);
			pstmt.setString(2, transformarFecha(fecha));
			pstmt.setInt(3, Integer.parseInt(categoria));
			pstmt.setDouble(4, new Double(monto.replace(',', '.')));
			pstmt.setInt(5, Integer.parseInt(idUsuario));
			pstmt.executeUpdate();
			ResultSet rs = pstmt.getGeneratedKeys();
			rs.next();
			return rs.getInt(1);
	}
	
	
	public List<Gasto> getTodosGastos(String idUsuario) throws SQLException, ClassNotFoundException, NamingException{
		List<Gasto> listaGastos = new ArrayList<Gasto>();
			Connection conn = DBManager.getInstance().getConnection();
			PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM gastos.gastos g INNER JOIN gastos.categoria c ON g.id_categoria = c.id WHERE g.id_usuario = ?");
			pstmt.setInt(1, Integer.parseInt(idUsuario));
			ResultSet rs = pstmt.executeQuery();
			while(rs.next()){
				SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
				Categoria c = new Categoria();
				c.setId(rs.getInt(7));
				c.setNombre(rs.getString(8));
				
				Gasto g = new Gasto();
				g.setCategoria(c);
				g.setId(rs.getInt(1));
				g.setDescripcion(rs.getString(2));
				g.setFecha(sdf.format(rs.getDate(3)));
				DecimalFormat twoDForm = new DecimalFormat("#.##");
				g.setMonto(Double.valueOf(twoDForm.format(rs.getDouble(5))));
				
				listaGastos.add(g);
			}
		return listaGastos;
	}
	
	

	public List<GastoVO> listarGastos(String descripcion, String fecha,
			String fechaInicio, String fechaFin, String monto,
			String categoria, String idUsuario, String agrupar) throws SQLException, ClassNotFoundException, NamingException {
		List<GastoVO> listaGastos = new ArrayList<GastoVO>();
		Connection conn = DBManager.getInstance().getConnection();
		
		int parametrosId = 1;
		
		HashMap<Integer,String> parametrosHash = new HashMap<Integer,String>();
		parametrosHash.put(parametrosId, idUsuario);
		parametrosId++;
		String query = "";
		
		if("1".equalsIgnoreCase(agrupar)){
			query = "SELECT c.nombre,sum(g.monto) as 'TOTAL' from gastos.gastos g inner join gastos.categoria c on g.id_categoria = c.id WHERE g.id_usuario = ?";
		}else{
			query = "SELECT * FROM gastos.gastos g INNER JOIN gastos.categoria c ON g.id_categoria = c.id WHERE g.id_usuario = ?";	
		}
		
		if(descripcion!=null && !"".equalsIgnoreCase(descripcion)){
			descripcion = "%" + descripcion + "%";
			query += " and g.descripcion like ?";
			parametrosHash.put(parametrosId, descripcion);
			parametrosId++;
		}
		
		if(fecha!=null && !"".equalsIgnoreCase(fecha)){
			query += " and g.fecha = DATE(?)";
			parametrosHash.put(parametrosId, transformarFecha(fecha));
			parametrosId++;
		}
		
		if(fechaInicio!=null && !"".equalsIgnoreCase(fechaInicio) &&  fechaFin!=null && !"".equalsIgnoreCase(fechaFin)){
			query += " and g.fecha BETWEEN DATE(?) AND DATE(?)";
			parametrosHash.put(parametrosId, transformarFecha(fechaInicio));
			parametrosId++;
			parametrosHash.put(parametrosId, transformarFecha(fechaFin));
			parametrosId++;
		}else if((fechaInicio==null || "".equalsIgnoreCase(fechaInicio)) &&  fechaFin!=null && !"".equalsIgnoreCase(fechaFin)){
			query += " and g.fecha <= DATE(?)";
			parametrosHash.put(parametrosId, transformarFecha(fechaFin));
			parametrosId++;
		}else if((fechaFin==null || "".equalsIgnoreCase(fechaFin)) &&  fechaInicio!=null && !"".equalsIgnoreCase(fechaInicio)){
			query += " and g.fecha >= DATE(?)";
			parametrosHash.put(parametrosId, transformarFecha(fechaInicio));
			parametrosId++;
		}
		
		if(monto!=null && !"".equalsIgnoreCase(monto)){
			query += " and g.monto = CAST(? AS DECIMAL(10,2))";
			parametrosHash.put(parametrosId, monto);
			parametrosId++;
		}
		if(categoria!=null && !"".equalsIgnoreCase(categoria)){
			query += " and g.id_categoria = ?";
			parametrosHash.put(parametrosId, categoria);
			parametrosId++;
		}
		if("1".equalsIgnoreCase(agrupar)){
			query += " group by c.nombre";
		}else{
			query += " order by g.fecha";	
		}
		
		PreparedStatement pstmt = conn.prepareStatement(query);
		
		for(Integer key: parametrosHash.keySet()){
			pstmt.setString(key, parametrosHash.get(key));
		}
		ResultSet rs = pstmt.executeQuery();
		while (rs.next()) {
			GastoVO g = new GastoVO();
			if("1".equalsIgnoreCase(agrupar)){
				g.setNombreCategoria(rs.getString(1));
				DecimalFormat twoDForm = new DecimalFormat("#.##");
				g.setMonto(Double.valueOf(twoDForm.format(rs.getDouble(2))));
				g.setMontoString(String.valueOf(g.getMonto()));
			}else{
				SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
				g.setNombreCategoria(rs.getString(8));
				g.setId(String.valueOf(rs.getInt(1)));
				g.setDescripcion(rs.getString(2));
				g.setFecha(sdf.format(rs.getDate(3)));
				DecimalFormat twoDForm = new DecimalFormat("#.##");
				g.setMonto(Double.valueOf(twoDForm.format(rs.getDouble(5))));
				g.setMontoString(String.valueOf(g.getMonto()));
			}
			listaGastos.add(g);
		}
		return listaGastos;
	}
	
	private String transformarFecha(String date){
		String[] fecha = date.split("-");
		return fecha[2] + "-" + fecha[1] + "-" + fecha[0];
	}

}
